import Client from './base';
import AliOSS from 'ali-oss';
import { computeMd5, getFileSuffix } from '../utils';

export default class OSSClient extends Client {
    run(callback) {
        const { file, id } = this;
        const config = this.config;
        const { onProgress, onSuccess, onError } = callback;

        /* "path/to/file_name.ext" */
        const key = `${config.path}${computeMd5(file)}.${getFileSuffix(file)}`;
        const disposition = `attachment;filename=${encodeURIComponent(file.name)}`;
        const options = {
            progress: (progress, cpt, res) => {
                this.abortCheckpoint = cpt;

                onProgress && onProgress({ id, progress: { percent: progress * 100 } });
            },
            parallel: 3,
            partSize: 102400,
            headers: {
                'x-oss-callback': config.callBackBody,
                'content-disposition': disposition
            }
        };

        this.client = new AliOSS(config);

        this.abortCheckpoint = null;
        this.client
            .multipartUpload(key, file, { ...options })
            .then((data) => {
                onSuccess({
                    id,
                    data: {
                        name: file.name,
                        size: file.size,
                        hash: data.etag.replace(/"/g, '').replace(/-.*$/, ''),
                        host: config.host,
                        url: data.name,
                        ispType: 'oss'
                    }
                });
            })
            .catch((info) => {
                if (info.name === 'SecurityTokenExpiredError') {
                    onError({ id, info: { code: 401, message: 'The security token you provided has expired.' } });
                } else {
                    onError({ id, info });
                }
            });
    }

    abort() {
        // 当一个分片上传事件被取消后，无法再使用该uploadId进行任何操作，已上传的分片数据会被删除。
        if (this.abortCheckpoint) {
            this.client.abortMultipartUpload(this.abortCheckpoint.name, this.abortCheckpoint.uploadId);
        }
    }
}
